import httpHandle from "./wrapping"
import onValidationHandle from "./validation"

/**
 * @param {string} url
 * @param {object} options
 * @returns {Promise}
 */
function request(url, options = {}) {
	return httpHandle.request(url, options)
}
request.get = (url, params, option = {}) => {
	const options = {
		...option,
		url,
		method: "GET",
		data: params,
	}
	return httpHandle.request(options)
}
request.post = (url, data, option = {}) => {
	const options = {
		...option,
		url,
		method: "POST",
		data,
	}
	return httpHandle.request(options)
}
request.put = (url, data, option = {}) => {
	const options = {
		...option,
		url,
		method: "PUT",
		data,
	}
	return httpHandle.request(options)
}
request.delete = (url, data, option = {}) => {
	const options = {
		...option,
		url,
		method: "DELETE",
		data,
	}
	return httpHandle.request(options)
}

export const axios = request

/**
 *
 * @param {object} option
 * @returns {Promise}
 */
export function http(option = {}) {
	if (option.data == undefined || option.data == null) option.data = {}
	if (option.validation == undefined || option.validation == null) option.validation = {}
	const validationKey = Object.keys(option.validation)
	for (let i = 0; i < validationKey.length; i++) {
		const key = validationKey[i]
		const rule = option.validation[key]
		const value = option.data[key]

		const error = onValidationHandle(rule, value)
		if (error) {
			return Promise.reject(error)
		}
	}
	option.method = option.method.toLocaleLowerCase()
	if (typeof option.data == "string") {
		option.dataType = option.dataType || "query"
	} else {
		if (option.method == "get") {
			option.dataType = option.dataType || "query"
		} else if (option.method == "post") {
			option.dataType = option.dataType || "body"
		}
	}
	if (option.dataType == "query") {
		if (typeof option.data == "string") return request[option.method](option.url + option.data)
		else {
			const query = Object.keys(option.data).map(key => `${key}=${option.data[key]}`)
			return request[option.method](option.url + "?" + query.join("&"))
		}
	}
	return request[option.method](option.url, option.data, option)
}

http.get = (url, options = {}) => {
	return http({
		url,
		method: "GET",
		...options,
	})
}
http.post = (url, options = {}) => {
	return http({
		url,
		method: "POST",
		...options,
	})
}
http.put = (url, options = {}) => {
	return http({
		url,
		method: "PUT",
		...options,
	})
}
http.delete = (url, options = {}) => {
	return http({
		url,
		method: "DELETE",
		...options,
	})
}
